<?php

class BaseUser {
	
	protected $db;
	public $user = array();
	public $users_custom_schema;
	protected $site;
	private $user_tables = array();
	private $password_regex;
	
	public function __construct($user_id=null) {
		global $db, $site, $env;
		$this->db = $db;
		$this->site = $site;
		$this->password_regex = isset($env['password']['regex']) ? $env['password']['regex'] : '/.+/';
		
		$this->users_custom_schema = array_slice($this->db->fetchAll("DESCRIBE cms_users_custom_{$site['id']}"), 1);
		for($i=0;$i<sizeof($this->users_custom_schema);$i++) {
			$type = preg_extract("/^(.*?)(\((.*)\))?( unsigned)?$/", $this->users_custom_schema[$i]['Type']);
			$this->users_custom_schema[$i]['Type'] = $type[0];
			
			if (in_array($this->users_custom_schema[$i]['Type'], array('enum', 'set'))) {
				$this->users_custom_schema[$i]['Options'] = preg_extract_all("/'(.*?)'/", $type[2]);
				$this->users_custom_schema[$i]['Options'] = $this->users_custom_schema[$i]['Options'][0];
			} elseif (in_array($this->users_custom_schema[$i]['Type'], array('real', 'double', 'float', 'decimal', 'numeric'))) {
				list($this->users_custom_schema[$i]['Length'], $this->users_custom_schema[$i]['Decimals']) = preg_extract("/(\d+),(\d+)/", $type[2]);
			} elseif (in_array($this->users_custom_schema[$i]['Type'], array('tinytext', 'mediumtext', 'text', 'longtext', 'tinyblob', 'mediumblob', 'blob', 'longblob'))) {
				// do nothing
			} else {
				$this->users_custom_schema[$i]['Length'] = $type[2];
			}
			
			$this->users_custom_schema[$i]['meta'] = $db->fetchRow("SELECT * FROM cms_users_custom_meta WHERE (site_id=? OR site_id=0) AND field=?", array($this->site['id'], $this->users_custom_schema[$i]['Field']));
		}
		
		// TODO: EXPLAIN
		$all_tables = $db->fetchCol("SHOW TABLES");
		foreach ($all_tables as $table) {
			if (preg_match("/^(.+)_users$/", $table, $matches) and $matches[1] != 'cms') {
				$this->user_tables[] = $matches[1];
			}
		}
		
		if (is_numeric($user_id)) {
			$this->user['id'] = $user_id;

			// core data from main table
			$this->user['core'] = $this->db->fetchRow("SELECT * FROM cms_users WHERE site_id=? AND id=?", array($this->site['id'], $user_id));
			unset($this->user['core']['id']);
			if (!$this->user['core']) throw new Exception('Invalid user ID');
			
			// custom data from site specific table
			$this->user['custom'] = $this->db->fetchRow("SELECT * FROM cms_users_custom_{$site['id']} WHERE user_id=?", $user_id);
			unset($this->user['custom']['user_id']);
			foreach($this->users_custom_schema as $field) {
				if ($field['Type'] == 'set') {
					$this->user['custom'][$field['Field']] = explode(',', $this->user['custom'][$field['Field']]);
				}
			}
			
			// unserialize the access rights
			$this->user['core']['access_rights'] = unserialize($this->user['core']['access_rights']);
			
			// foreach table in the database named *_users, get the data from these
			$this->user['user_tables'] = array();
			foreach ($this->user_tables as $table_prefix) {
				$this->user['user_tables'][$table_prefix] = $this->db->fetchRow("SELECT * FROM {$table_prefix}_users WHERE user_id=?", $user_id);
				if (!is_array($this->user['user_tables'][$table_prefix])) $this->user['user_tables'][$table_prefix] = array();
				unset($this->user['user_tables'][$table_prefix]['user_id']);
			}
			
		} else {
			$this->user['core']        = array();
			
			$this->user['custom']      = array();
			foreach($this->users_custom_schema as $field) {
				$this->user['custom'][$field['Field']] = $field['Default'];
			}
			
			$this->user['user_tables'] = array();
			foreach ($this->user_tables as $table_prefix) {
				$this->user['user_tables'][$table_prefix] = array();
			}
		}
		
	}
	
	public function save(&$errors='') {
		if ($this->is_valid($errors)) {
			if (isset($this->user['password1'])) {
				$this->user['core']['password'] = Password::hash($this->user['password1']);
			}
			
			if ($this->user['core']['display_name'] == '') $this->user['core']['display_name'] = trim($this->user['core']['first_name'] . ' ' . $this->user['core']['last_name']);
			foreach ($this->user['custom'] as $key => $value) { if ($value == '') { $this->user['custom'][$key] = new Zend_Db_Expr('NULL'); } }
			
			$this->user['core']['access_rights'] = serialize(isset($this->user['core']['access_rights']) ? $this->user['core']['access_rights'] : array());
			
			if (isset($this->user['id'])) {
				$this->db->update('cms_users', array_merge($this->user['core'], array('modified' => new Zend_Db_Expr('NOW()'))), "id={$this->user['id']}");
			} else {
				$this->db->insert('cms_users', array_merge($this->user['core'], array('site_id' => $this->site['id'], 'created' => new Zend_Db_Expr('NOW()'), 'modified' => new Zend_Db_Expr('NOW()'))));
				$this->user['id'] = $this->db->lastInsertId();	
			}
			
			foreach($this->users_custom_schema as $field) {
				if ($field['Type'] == 'set') {
					$this->user['custom'][$field['Field']] = implode(',', $this->user['custom'][$field['Field']]);
				}
			}
			try {
				$this->db->insert("cms_users_custom_{$this->site['id']}", array_merge(array('user_id' => $this->user['id']), $this->user['custom']));
			} catch(Exception $e) {
				if ($this->user['custom']) $this->db->update("cms_users_custom_{$this->site['id']}", $this->user['custom'], "user_id={$this->user['id']}");
			}
			
			// TODO: EXPLAIN
			foreach($this->user_tables as $table_prefix) {
				try {
					$this->db->insert("{$table_prefix}_users", array_merge(array('user_id' => $this->user['id']), $this->user['user_tables'][$table_prefix]));
				} catch(Exception $e) {
					$this->db->update("{$table_prefix}_users", $this->user['user_tables'][$table_prefix], "user_id={$this->user['id']}");
				}
			}
			
			// regenerate the user object
			$this->__construct($this->user['id']);
			return $this->user['id'];
			
		} else {
			return false;
		}
	}
	
	public function is_valid(&$errors='') {
		$errors = array();
		if (strlen($this->user['core']['username']) < 5) $errors[] = 'USER_LEN';
		if (!preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+\.([a-zA-Z0-9\._-]+)+$/" , $this->user['core']['email'])) $errors[] = 'EMAIL';
		if ($this->db->fetchOne("SELECT id FROM cms_users WHERE username=? AND id!=?", array($this->user['core']['username'], isset($this->user['id'])?$this->user['id']:''))) $errors[] = 'USER_UNIQUE';
		if ($this->db->fetchOne("SELECT id FROM cms_users WHERE email=? AND site_id=? AND id!=?", array($this->user['core']['email'], $this->site['id'], isset($this->user['id'])?$this->user['id']:''))) $errors[] = 'EMAIL_UNIQUE';
		if (isset($this->user['password1'])	and !preg_match($this->password_regex, $this->user['password1'])) $errors[] = 'PASS_REGEX';
		if (isset($this->user['password1'])	and isset($this->user['password2']) and $this->user['password1'] != $this->user['password2']) $errors[] = 'PASS_MATCH';
		if (!$this->user['core']['first_name']) $errors[] = 'FIRST_NAME';
		if (!$this->user['core']['last_name']) $errors[] = 'LAST_NAME';
		foreach($this->users_custom_schema as $field) {
			// butt in here to convert the date if in dropdown/array format
			if ($field['Type'] == 'date' and is_array($this->user['custom'][$field['Field']])) $this->user['custom'][$field['Field']] = $this->user['custom'][$field['Field']]['y'] . '-' . $this->user['custom'][$field['Field']]['m'] . '-' . $this->user['custom'][$field['Field']]['d'];
			
			if (isset($field['meta']) and $field['meta']['required'] and isset($this->user['custom'][$field['Field']]) and !preg_match($field['meta']['regex'], $this->user['custom'][$field['Field']])) $errors[] = 'CUSTOM:' . $field['meta']['error'];
		}
		if (sizeof($errors)) return false;
		return true;
	}
	
}